import requests
from bs4 import BeautifulSoup
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 网页URL
url = "https://www.kylc.com/stats/global/yearly_per_country/g_population_total/chn-jpn-kor.html"

# 发送HTTP请求
response = requests.get(url)
response.raise_for_status()  # 确保请求成功

# 解析HTML
soup = BeautifulSoup(response.text, 'html.parser')

# 查找表格
table = soup.find('table', class_='table')

# 解析表格标题
header_rows = table.find('thead').find_all('tr')
headers = []
# 第一行标题
for th in header_rows[0].find_all('th'):
    # 这里应该忽略跨列的th标签，只使用不跨列的标题
    colspan = th.get('colspan', 1)
    if colspan == "1":
        headers.append(th.text.strip())
    else:
        # 对每个跨列标题，添加其对应的细分标题
        sub_headers = header_rows[1].find_all('th')[:int(colspan)]
        headers.extend([f"{th.text.strip()} {sub_header.text.strip()}" for sub_header in sub_headers])
        header_rows[1].find_all('th')[:int(colspan)] = []  # 删除已处理的标题

# 解析表格数据
data = []
rows = table.find('tbody').find_all('tr')
for row in rows:
    cols = row.find_all('td')
    cols = [ele.text.strip() for ele in cols]
    data.append(cols)  # 直接使用cols，因为已确保与标题数量相匹配

# 创建DataFrame
df = pd.DataFrame(data, columns=headers)

# 保存到Excel文件
df.to_excel('中国、日本、韩国历年人口总数统计.xlsx', index=False)

print("数据已保存到Excel文件。")




df = pd.read_excel('中国、日本、韩国历年人口总数统计.xlsx')
print(df.head(4))
# 第一步：处理缺失值
df.dropna(inplace=True)  # 删除任何含有缺失值的行

# 第二步：处理错误数据和特征提取
import re

def extract_population(value):
    # 使用正则表达式提取数字部分
    match = re.search(r'\(([\d,]+)\)', value)
    return int(match.group(1).replace(',', '')) if match else None

# 应用提取函数到每个国家的人口数据列
df['中国 人口(数字)'] = df['中国 人口'].apply(extract_population)
df['日本 人口(数字)'] = df['日本 人口'].apply(extract_population)
df['韩国 人口(数字)'] = df['韩国 人口'].apply(extract_population)

# 将百分比字符串转换为浮点数
df['中国 占世界%'] = df['中国 占世界%'].str.rstrip('%').astype(float) / 100
df['日本 占世界%'] = df['日本 占世界%'].str.rstrip('%').astype(float) / 100
df['韩国 占世界%'] = df['韩国 占世界%'].str.rstrip('%').astype(float) / 100

# 第三步：特征提取完成
print(df.head())
df.to_excel('中国、日本、韩国历年人口总数统计（数据清理）.xlsx', index=False)


df = pd.read_excel('中国、日本、韩国历年人口总数统计（数据清理）.xlsx')

# 数据分布分析与可视化
plt.figure(figsize=(10, 6))
sns.lineplot(data=df, x='年份 人口', y='中国 人口(数字)', label='中国')
sns.lineplot(data=df, x='年份 人口', y='日本 人口(数字)', label='日本')
sns.lineplot(data=df, x='年份 人口', y='韩国 人口(数字)', label='韩国')
plt.title('各国人口随年份的变化')
plt.xlabel('年份')
plt.ylabel('人口数量')
plt.legend()
plt.savefig('各国人口随年份的变化')

plt.show()

# 数据占比分析与可视化
plt.figure(figsize=(10, 6))
sns.barplot(data=df, x='年份 人口', y='中国 占世界%', color='blue', label='中国')
sns.barplot(data=df, x='年份 人口', y='日本 占世界%', color='red', label='日本')
sns.barplot(data=df, x='年份 人口', y='韩国 占世界%', color='green', label='韩国')
plt.title('各国人口占世界百分比的变化')
plt.xlabel('年份')
plt.ylabel('世界人口占比')
plt.legend()
plt.savefig('各国人口占世界百分比的变化')

plt.show()
# 堆积面积图
plt.figure(figsize=(12, 6))
plt.stackplot(df['年份 人口'], df['中国 占世界%'], df['日本 占世界%'], df['韩国 占世界%'], labels=['中国', '日本', '韩国'])
plt.title('三国人口占世界百分比的堆积面积图')
plt.xlabel('年份')
plt.ylabel('占世界百分比')
plt.legend(loc='upper left')
plt.savefig('三国人口占世界百分比的堆积面积图')

plt.show()

# 箱型图
plt.figure(figsize=(12, 6))
sns.boxplot(data=df[['中国 人口(数字)', '日本 人口(数字)', '韩国 人口(数字)']])
plt.title('三国人口数据的箱型图')
plt.ylabel('人口数量')
plt.xlabel('国家')
plt.savefig('三国人口数据的箱型图')
plt.show()